package org.grayrabbit.cms.action.generate;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.grayrabbit.cms.constant.ConfigCode;
import org.grayrabbit.cms.constant.ConstantOperCode;
import org.grayrabbit.cms.constant.ConstantWebApp;
import org.grayrabbit.cms.constant.DictionaryStaticValues;
import org.grayrabbit.cms.entity.Admin;
import org.grayrabbit.cms.entity.Category;
import org.grayrabbit.cms.entity.Content;
import org.grayrabbit.cms.entity.Site;
import org.grayrabbit.cms.entity.Survey;
import org.grayrabbit.cms.entity.Topic;
import org.grayrabbit.cms.publish.api.PublishInfo;
import org.grayrabbit.cms.publish.api.PublishInfo.LogInfo;
import org.grayrabbit.cms.publish.api.Publishable;
import org.grayrabbit.cms.service.category.CategoryService;
import org.grayrabbit.cms.service.content.ContentService;
import org.grayrabbit.cms.service.plugins.SurveyService;
import org.grayrabbit.cms.service.site.SiteService;
import org.grayrabbit.cms.service.system.ConfigService;
import org.grayrabbit.cms.service.topic.TopicService;
import org.grayrabbit.cms.util.IpUtil;
import org.grayrabbit.cms.vo.category.CategoryBean;
import org.grayrabbit.cms.vo.content.ContentBean;
import org.grayrabbit.cms.vo.plugins.SurveyBean;
import org.grayrabbit.cms.vo.site.SiteBean;
import org.grayrabbit.cms.vo.topic.TopicBean;
import org.grayrabbit.dao.util.Page;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
@Controller
@Scope("prototype")
public class PublishAction extends GenAction {
	private static final long serialVersionUID = -1666617049685117317L;
	private  static Logger log = LoggerFactory.getLogger(PublishAction.class);
	@Autowired
	@Qualifier("publishableImpl")
	private Publishable publishable;
	
	@Autowired
	@Qualifier("topicServiceImpl")
	private TopicService topicService; 
	
	@Autowired
	@Qualifier("siteServiceImpl")
	private SiteService siteService;
	
	@Autowired
	@Qualifier("surveyServiceImpl")
	private SurveyService surveyService;
	
	@Autowired
	@Qualifier("configServiceImpl")
	private ConfigService configService;
	
	@Autowired
	@Qualifier("categoryServiceImpl")
	private CategoryService categoryService;
	
	@Autowired
	@Qualifier("contentServiceImpl")
	private ContentService contentService;
	
	private String type;
	private String targets;
	private InputStream inputStream;
	private SiteBean site;
	private CategoryBean cat;
	private ContentBean content;
	private TopicBean topic;
	private SurveyBean survey;
	private Page<Site> sitePage;
	private Page<Category> catPage;
	private Page<Content> contentPage;
	private Page<Topic> topicPage;
	private Page<Survey> surveyPage;
	private String catIdTargets;
	private String pflag;	//发布类型标识
	private int percent;
	private String info;
	private Date now;
	private String percentKey;
	private String cflag;
	
	public String getCflag() {
		return cflag;
	}


	public void setCflag(String cflag) {
		this.cflag = cflag;
	}


	public String getPercentKey() {
		return percentKey;
	}


	public void setPercentKey(String percentKey) {
		this.percentKey = percentKey;
	}


	public Date getNow() {
		return now;
	}


	public void setNow(Date now) {
		this.now = now;
	}


	public int getPercent() {
		return percent;
	}


	public void setPercent(int percent) {
		this.percent = percent;
	}


	public String getInfo() {
		return info;
	}


	public void setInfo(String info) {
		this.info = info;
	}


	public String getPflag() {
		return pflag;
	}


	public void setPflag(String pflag) {
		this.pflag = pflag;
	}


	public String getCatIdTargets() {
		return catIdTargets;
	}


	public void setCatIdTargets(String catIdTargets) {
		this.catIdTargets = catIdTargets;
	}


	public SurveyBean getSurvey() {
		return survey;
	}


	public void setSurvey(SurveyBean survey) {
		this.survey = survey;
	}


	public Page<Survey> getSurveyPage() {
		return surveyPage;
	}


	public void setSurveyPage(Page<Survey> surveyPage) {
		this.surveyPage = surveyPage;
	}


	public Page<Site> getSitePage() {
		return sitePage;
	}


	public void setSitePage(Page<Site> sitePage) {
		this.sitePage = sitePage;
	}


	public Page<Category> getCatPage() {
		return catPage;
	}


	public void setCatPage(Page<Category> catPage) {
		this.catPage = catPage;
	}


	public Page<Content> getContentPage() {
		return contentPage;
	}


	public void setContentPage(Page<Content> contentPage) {
		this.contentPage = contentPage;
	}


	public Page<Topic> getTopicPage() {
		return topicPage;
	}


	public void setTopicPage(Page<Topic> topicPage) {
		this.topicPage = topicPage;
	}


	public SiteBean getSite() {
		return site;
	}


	public void setSite(SiteBean site) {
		this.site = site;
	}


	public CategoryBean getCat() {
		return cat;
	}


	public void setCat(CategoryBean cat) {
		this.cat = cat;
	}


	public ContentBean getContent() {
		return content;
	}


	public void setContent(ContentBean content) {
		this.content = content;
	}


	public TopicBean getTopic() {
		return topic;
	}


	public void setTopic(TopicBean topic) {
		this.topic = topic;
	}


	public InputStream getInputStream() {
		return inputStream;
	}


	public void setInputStream(InputStream inputStream) {
		this.inputStream = inputStream;
	}
	
	

	public String getType() {
		return type;
	}


	public void setType(String type) {
		this.type = type;
	}


	public String getTargets() {
		return targets;
	}


	public void setTargets(String targets) {
		this.targets = targets;
	}



	public List<String> getTargetObjects(){
		//FIXME 此处需要检查 2012-04-17
		/*if("associator".equals(type) && StringUtils.isBlank(targets)){
			return showAssociatorsService.findAllAssociatorsIds();
		} */
		if(StringUtils.isNotBlank(targets)){
			List<String> list = new ArrayList<String>();
			String[] arr = targets.split(",");
			for(String s : arr){
				list.add(s);
			}
			return list;
		}
		return null;
	}
	
	/**
	 * 参数：/preview.action?type=index&targets=1,2
	 * @return
	 * @throws Exception
	 */
	@Action(value="preview",
			results={@Result(name="success", type="stream",params={"contentType","text/html"})})
	public String preview(){
		Admin admin = (Admin) getSessionValue(ConstantWebApp.CURRENT_ADMIN);
		Site currentSite = (Site) getSessionValue(ConstantWebApp.CURRENT_SITE);
		List<String> targets = getTargetObjects();
		try{
			if(currentSite!=null && targets!=null && targets.size() ==1){
				inputStream = new ByteArrayInputStream(publishable.preview(currentSite,this.type, targets, admin, IpUtil.getClientIp(getRequest())).toByteArray());
				return "success";
			}else{
				return "fail";
			}
		}catch(Exception e) {
			return renderHtml("动态预览出现异常,请确认站点主题和模板的选择是否正确！");
		}
	}
	
	@Action(value="publish-content",
			results={@Result(name="reload",type="redirectAction",params={"actionName","../content/content-list?content.category.categoryId=${content.category.categoryId}"})}
	)
	
	public String publishContent() throws Exception{
		List<String> list = getTargetObjects();
		Admin admin = (Admin) getSessionValue(ConstantWebApp.CURRENT_ADMIN);
		Site currentSite = (Site) getSessionValue(ConstantWebApp.CURRENT_SITE);
		int pageSize =(configService.getConfigByAttrKey(ConfigCode.PUBLISH_LIST_PAGE_SIZE)==null
				||configService.getConfigByAttrKey(ConfigCode.PUBLISH_LIST_PAGE_SIZE).getConfigAttrValue()==null)?20:Integer.parseInt(configService.getConfigByAttrKey(ConfigCode.PUBLISH_LIST_PAGE_SIZE).getConfigAttrValue());
		int pageNum =(configService.getConfigByAttrKey(ConfigCode.PUBLISH_LIST_PAGE_NUM)==null
				||configService.getConfigByAttrKey(ConfigCode.PUBLISH_LIST_PAGE_NUM).getConfigAttrValue()==null)?20:Integer.parseInt(configService.getConfigByAttrKey(ConfigCode.PUBLISH_LIST_PAGE_NUM).getConfigAttrValue());
		publishable.publish(currentSite,  type, pflag,list, admin, IpUtil.getClientIp(getRequest()), false, pageSize, pageNum);
		return RELOAD;
	}
	
	@Action(value="publish")
	public String publish() throws Exception{
		Admin admin = (Admin) getSessionValue(ConstantWebApp.CURRENT_ADMIN);
		Site currentSite = (Site) getSessionValue(ConstantWebApp.CURRENT_SITE);
		String info = "";
		String ip = IpUtil.getClientIp(getRequest());
		List<String> ids = getTargetObjects();
		String publishType = getPublishType(pflag,type,ids);
		if(ids==null||!StringUtils.isNotBlank(publishType)){
			info = "{flag:false}";
		}else{
			try {
				
				log.info("创建生成线程……");
				String taskId = publishable.publish(currentSite, type,pflag , ids, admin, ip, false, 20, 10);
				info = "{flag:true,percentKey:'";
				info += publishType + "',id:'"+taskId+"'}";
			} catch (Exception e) {
				log.info("启动线程出现异常：{}",e);
				info = "{flag:false,info:'启动出现异常,请检查系统配置文件!'}";
			}
		}
		return renderText(info);			
	}
	
	private String getPublishType(String pflag,String type,List<String> list){
		String ids = "";
		for(String obj : list){
			if(Publishable.SITE_GEN.equals(type)){
				if(!this.authLicence(ConstantOperCode.CAT_CAT_GEN, obj)){
					continue;
				}
			}else if(Publishable.TOPIC_GEN.equals(type)){
				if(!this.authLicence(ConstantOperCode.TOPIC_TOPIC_GEN, obj)){
					continue;
				}
			}
			ids+=obj+"_";
		}
		if(!StringUtils.isNotBlank(ids)){
			return null;
		}else{
			return type+"_"+pflag+"_"+ids;
		}
	}
	
	@Action(value="stop-percent")
	public String stopPercent(){
		try {
			log.info("用户取消发布操作");
			publishable.stop(percentKey);
		} catch (Exception e) {
			log.info("用户取消发布操作失败{}",e);
			return this.renderText("{falg:false}");
		}
		return this.renderText("{falg:true}");
	}
	
	@Action(value="list-percent")
	public String retrunValue(){
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		PublishInfo pi= publishable.read(percentKey, 0);
		StringBuffer sb = new StringBuffer("{");
		sb.append("percent:'"+pi.getPercent()+"',");
		sb.append("loginfo:'");
		for(LogInfo li:pi.getLoginfos()){
			sb.append(li.isError()+"_"+sdf.format(li.getTime())+":"+li.getLogInfo().replaceAll("\\\\", "/")+"@@");
		}
		sb.append("',successNum:'"+pi.getSuccessNum());
		sb.append("',failNum:'"+pi.getFailureNum());
		sb.append("',totalNum:'"+pi.getTotal());
		sb.append("'}");
		return renderText(sb.toString());
	}
	
	@Action(value="list-site")
	public String listSite(){
		if(site!=null&&StringUtils.isNotBlank(site.getSiteId())){
			site = (SiteBean)dozer.map(siteService.getSite(site.getSiteId()),SiteBean.class);
		}
		now = new Date();
		return SUCCESS;
	}
	
	@Action(value="list-cat")
	public String listCat(){
		if(site!=null&&StringUtils.isNotBlank(site.getSiteId())){
			site = (SiteBean)dozer.map(siteService.getSite(site.getSiteId()),SiteBean.class);
		}
		now = new Date();
		return SUCCESS;
	}
	
	@Action(value="list-topic")
	public String listTopic(){
		topic = new TopicBean();
		topic.setSite(site);
		topic.setTopicStatus(DictionaryStaticValues.TOPIC_STATUS_SUCCESS);
		topicPage = topicService.getPage(topic);
		return SUCCESS;
	}
	
	@Action(value="list-survey")
	public String listSurvey(){
		survey = new SurveyBean();
		if(site!=null&&StringUtils.isNotBlank(site.getSiteId())){
			survey.setSite(site);
		}
		survey.setSurveyStatus(true);
		surveyPage = surveyService.getPage(survey);
		return SUCCESS;
	}
	
	@Action(value="cat-detail")
	public String categoryDetail(){
		String info = "{catName:'";
		String catName = "";
		String contentNum = "";
		String contentPub = "";
		String contentSuc = "";
		if(StringUtils.isNotBlank(catIdTargets)){
			for(String catId:catIdTargets.split(",")){
				Category cat = categoryService.findCatById(catId);
				catName+=cat.getCatName()+"@";
				ContentBean contentBean = new ContentBean();
				contentBean.setCategory(cat);
				List<Content> list = contentService.findAll(contentBean);
				int i = 0;
				int j = 0;
				for(Content item:list){
					if(DictionaryStaticValues.CONTENT_STATUS_SUCCESS.equals(item.getContentStatus())){
						i++;
					}
					if(DictionaryStaticValues.CONTENT_STATUS_PUBLISH.equals(item.getContentStatus())){
						j++;
					}
				}
				contentNum+=contentService.findAll(contentBean).size()+"@";
				contentSuc+=i+"@";
				contentPub+=j+"@";
			}
		}
		info+=catName+"',contentNum:'"+contentNum+"',contentSuc:'"+contentSuc+"',contentPub:'"+contentPub+"'}";
		return renderText(info);
	}
 
}
